package com.gitee.wsl.net.ssdp.description.model.xml

import com.gitee.wsl.logger.Logger
import com.gitee.wsl.logger.info
import com.gitee.wsl.net.ssdp.description.xml.XmlElement
import kotlin.properties.Delegates

object ActionList{
    /**
     * Action defined by a UPnP Forum working committee. Each service is allowed to have >= 0 actions. If UPnP vendor
     * differentiates service by adding additional actions, repeat once for each additional action.
     * @param name          - Name of action. Shall not contain a hyphen character (“-”, 2D Hex in UTF8) nor a hash
     *                          character (“#”, 23 Hex in UTF-8). Case sensitive. First character shall be a USASCII
     *                          letter (“A”-“Z”, “a”-“z”), USASCII digit (“0”-“9”), an underscore (“_”), or
     *                          a non-experimental Unicode letter or digit greater than U+007F. Succeeding
     *                          characters Shall be a USASCII letter (“A”-“Z”, “a”-“z”), USASCII digit (“0”-“9”), an
     *                          underscore (“_”), a period (“.”), a Unicode combiningchar, an extender, or a
     *                          nonexperimental Unicode letter or digit greater than U+007F. The first three letters shall
     *                          not be “XML” in any combination of case.
     *                          For standard actions defined by a UPnP Forum working committee, Shall not
     *                          begin with “X_” nor “A_”.
     *                          For non-standard actions specified by a UPnP vendor and added to a standard
     *                          service, shall begin with “X_”, followed by a Vendor Domain Name, followed by
     *                          the underscore character (“_”), followed by the vendor-assigned action name.
     *                          The vendor-assigned action name shall comply with the syntax rules defined above.
     *                          String. Should be < 32 characters
     * @param argumentList  - Parameters defined for action
     */
    data class Action(
        val name: String,
        val argumentList: List<ArgumentList.Argument>? = null
    ) {
        /**
         * Facilitates flexible deserialization and conditional validation
         */
        companion object {
            fun fromXml(xml: XmlElement): Action {
                if (xml.tag != "action") {
                    throw IllegalArgumentException("Unexpected element ${xml.tag} in ActionList")
                }
                var nameS by Delegates.notNull<String>()
                var argsListO by Delegates.notNull<List<ArgumentList.Argument>>()

                xml.children?.forEach {
                    when (it.tag) {
                        "name" -> nameS = it.get()
                        "argumentList" -> argsListO = ArgumentList.fromXml(it)
                        else -> Logger.info("Unexpected tag ${it.tag}")
                    }
                }
                return Action(nameS, argsListO)
            }
        }
    }


    fun fromXml(xml: XmlElement): List<Action> = xml.children?.map(Action::fromXml) ?: emptyList()

}